package com.ccys.common.third.push.ios;



import com.eatthepath.pushy.apns.*;
import com.eatthepath.pushy.apns.util.ApnsPayloadBuilder;
import com.eatthepath.pushy.apns.util.SimpleApnsPayloadBuilder;
import com.eatthepath.pushy.apns.util.SimpleApnsPushNotification;
import com.eatthepath.pushy.apns.util.TokenUtil;
import com.eatthepath.pushy.apns.util.concurrent.PushNotificationFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import java.io.File;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * IOS  推送
 * <p>
 * 参考文档：
 * https://www.5axxw.com/wiki/content/ij997a
 * https://codeleading.com/article/13176434512/
 * 测试验证通过
 * @author Administrator
 */
@Slf4j
@Component
public class IosNotificationUtil {
    private static final String sAPNS_Cert_Path = "/ios/whitecoat-patient.p12";
    private static final String sAPNS_Cert_Key = "123456";
    // false 测试环境，true 正式环境
    private static final boolean environment = true;

    // 初始化APNS请求对象


    private static ApnsClient apnsClient = null;

    public static ApnsClient getAPNSConnect() {
        if (apnsClient == null) {
            try {
                ClassPathResource resource = new ClassPathResource(sAPNS_Cert_Path);
                apnsClient = new ApnsClientBuilder()
                    //设置信息包含服务器地址  ApnsClientBuilder.DEVELOPMENT_APNS_HOST 开发环境地址
                    //ApnsClientBuilder.PRODUCTION_APNS_HOST  对应生产环境
                    .setApnsServer(environment ? ApnsClientBuilder.PRODUCTION_APNS_HOST : ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
                    .setClientCredentials(resource.getFile(), sAPNS_Cert_Key)
                    //.setClientCredentials 包含  证书file 文件  证书对应的文件密码（找ios 开发确定导出密码）
                    //.setClientCredentials(new File("/path/to/certificate.p12"), "p12-file-password")
                    //.setConcurrentConnections(4) //并发
                    /*.setProxyHandlerFactory(new Socks5ProxyHandlerFactory(
                        // 代理地址
                        new InetSocketAddress("127.0.0.1", 17890), "username", "password"))*/

                    .build();
            } catch (Exception e) {
                log.error("ios get pushy apns client failed!");
                e.printStackTrace();
            }
        }
        return apnsClient;

    }


       /**
        * @description 推送消息到ios设备
        * @param deviceTokens 接收用户token
        * @param alertTitle  标题
        * @param alertBody  内容
        * @param contentAvailable  参数设置为 false 时，表示通知是一个静默推送，它会激活应用程序的后台处理逻辑，而不会在用户界面上显示通知。这样可以让应用程序在后台处理一些任务，例如同步数据、更新内容等
        * @param customProperty  自定义参数
        * @date     2024/1/16
        * @author   cloud fly
        */
    public static void push(List<String> deviceTokens, String alertTitle, String alertBody,
                            boolean contentAvailable, Map<String, String> customProperty) {
        long startTime = System.currentTimeMillis();
        ApnsClient apnsClient = getAPNSConnect();
        long total=deviceTokens.size();
        for (String deviceToken : deviceTokens) {

            ApnsPayloadBuilder payloadBuilder =new SimpleApnsPayloadBuilder();

            if(alertBody!=null) {
                payloadBuilder.setAlertBody(alertBody);
            }

            if(alertTitle !=null){
                payloadBuilder.setAlertTitle(alertTitle);
            }

            //如果badge小于0，则不推送这个右上角的角标，主要用于消息盒子新增或者已读时，更新此状态
            payloadBuilder.setBadgeNumber(1);

            //将所有的附加自定义参数全部放进去
            if(customProperty!=null) {
                for(Map.Entry<String, String> map:customProperty.entrySet()) {
                    payloadBuilder.addCustomProperty(map.getKey(),map.getValue());
                }
            }
            payloadBuilder.setContentAvailable(contentAvailable);
            String payload = payloadBuilder.build();
            final String token = TokenUtil.sanitizeTokenString(deviceToken);
            // 使用 Pushy 推送到具体的 deviceToken，需要指定推送的 topic。因为在 APNs 中，topic 是用来标识 App 的 bundle ID 和 APNs 证书的 （天ios的包名）
            SimpleApnsPushNotification pushNotification = new SimpleApnsPushNotification(deviceToken, "co.codigo.WhiteCoat.qa", payload);
            //发送消息回复返回值
            final PushNotificationFuture<SimpleApnsPushNotification, PushNotificationResponse<SimpleApnsPushNotification>>
                sendNotificationFuture = apnsClient.sendNotification(pushNotification);

            //监听--用以提高效率
            sendNotificationFuture.whenComplete((pushNotificationResponse, cause) -> {
                if (pushNotificationResponse != null) {
                    // Handle the push notification response as before from here.
                    if (pushNotificationResponse.isAccepted()) {
                        log.info("Push notification accepted by APNs gateway.");
                    } else {
                        log.error("Notification rejected by the APNs gateway: " +
                            pushNotificationResponse.getRejectionReason());
                        pushNotificationResponse.getTokenInvalidationTimestamp().ifPresent(timestamp -> {
                            log.error("\t…and the token is invalid as of " + timestamp);
                        });
                    }
                } else {
                    // Something went wrong when trying to send the notification to the
                    // APNs server. Note that this is distinct from a rejection from
                    // the server, and indicates that something went wrong when actually
                    // sending the notification or waiting for a reply.
                    cause.printStackTrace();
                }
            });

        }
        long endPushTime = System.currentTimeMillis();

        log.info("test pushMessage success. [共推送" + total + "个],time= " + (endPushTime - startTime) );
    }

    public static void main(String[] args)  {

        List<String> tokenList = new ArrayList<>();
        //tokenList.add("IQAAAACy0n3JAABJnxF_ibWhDJ0lI_4-GkuTuO62bd8YpWldlU6o3Uu_WH26sH3HG1FYaMMisDIopdyUBvVw6I36S-wpF93uPQC5hWVff1QaD1uI0w");
        // 这个ID测试推送成功
        tokenList.add("BF7FA0D364FFD94EDD11C4078012407DCB8771E24834EFF4D65A711AEEABA8D3");
        try {
            Map<String, String> customProperty = new HashMap<>();
            customProperty.put("id", "111");
            IosNotificationUtil.push(tokenList,"测试推送源昇科技","666666", true,customProperty);
        } catch (Exception e) {
            e.printStackTrace();
        }



    }


}